# datastore.py - Datastore access.
# Copyright 2010 Rob Myers <rob@robmyers.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

################################################################################
# imports
################################################################################

import post_data
import tweet

from google.appengine.ext import db

# "now" must always be the same for a single dgr run, 
# and must be datetime.datetime.now()

################################################################################
# DGR run
################################################################################

class DatastoreDgrRun(db.Model):
    """A particular run of a dgr"""
    dgr_yaml_path = db.StringProperty(required=True)
    run_datetime = db.DateTimeProperty(required=True)
    run_day = db.IntegerProperty(required=True)
    run_hour = db.IntegerProperty(required=True)
    time_of_day_keywords = db.StringListProperty(required=True)
    wff_search_response_xml = db.TextProperty(required=True)
    wff_keywords = db.StringListProperty(required=True)
    character_keywords = db.StringListProperty(required=True)
    emotional_state_keywords = db.StringListProperty(required=True)
    combined_keywords = db.StringListProperty(required=True)

def StoreDgrRun(replicator):
    """Store the DGR'S state for a particular run in the datastore"""
    run = DatastoreDgrRun(dgr_yaml_path=replicator.config_path,
                          run_datetime=replicator.current_time,
                          run_day=replicator.current_day,
                          run_hour=replicator.current_hour,
                          time_of_day_keywords=replicator.time_of_day_keywords,
                          wff_search_response_xml=replicator.wff_xml,
                          wff_keywords=replicator.wff_keywords,
                          emotional_state_keywords=\
                              replicator.emotional_state_keywords,
                          character_keywords=replicator.character_keywords,
                          combined_keywords=replicator.combined_keywords)
    run.put()


################################################################################
# Tweet that the DGR retweeted
################################################################################

class DatastoreTwitterSearchResponse(db.Model):
    """A tweet retweeted by a particular run of a dgr"""
    dgr_yaml_path = db.StringProperty(required=True)
    run_datetime = db.DateTimeProperty(required=True)
    who = db.StringProperty(required=True)
    what = db.StringProperty(required=True, multiline=True)
    where = db.StringProperty(required=True)
    tweet_id = db.StringProperty(required=True)
    terms = db.StringListProperty(required=True)

def StoreTwitterSearchResponse(dgr_yaml_path, now, tweet, terms):
    """Store the found tweet in the datastore"""
    twt = DatastoreTwitterSearchResponse(dgr_yaml_path=dgr_yaml_path,
                                         run_datetime=now,
                                         who=tweet.who,
                                         what=tweet.what,
                                         where=tweet.where,
                                         tweet_id=tweet.tweet_id,
                                         terms=terms)
    twt.put()


################################################################################
# A search result to format up and post
################################################################################

class DatastorePostData(db.Model):
    """PostData from a particular source broadast by a particular dgr run"""
    dgr_yaml_path = db.StringProperty(required=True)
    run_datetime = db.DateTimeProperty(required=True)
    source = db.StringProperty(required=True,choices=set(["flickr", "youtube",
                                                          "googlebooks", 
                                                          "lastfm"]))
    description =  db.StringProperty(multiline=True)
    title = db.StringProperty()
    user_name = db.StringProperty()
    user_url = db.StringProperty()
    source_url = db.StringProperty()
    image_url = db.StringProperty()
    embed_html = db.TextProperty()

def StorePostData(dgr_yaml_path, now, source, post_data):
    """Store the post_data in the datastore"""
    pd = DatastorePostData(dgr_yaml_path=dgr_yaml_path,
                           run_datetime=now,
                           source=source,
                           description=post_data.description,
                           title=post_data.title,
                           user_name=post_data.user_name,
                           user_url=post_data.user_url,
                           source_url=post_data.source_url,
                           image_url=post_data.image_url,
                           embed_html=post_data.embed_html)
    pd.put()

def AlreadyPostedUrl(dgr_yaml_path, source, url):
    """Find out whether the url has already been posted by this DGR"""
    match = db.GqlQuery("SELECT * FROM DatastorePostData " + 
                        " WHERE source = :1" +
                        " AND source_url = :2", source, url).get()
    return match != None
